#include <iostream>
using namespace std;

class State;
class Context;
class ConcreteStateB;
class ConcreteStateA;

class State {
public:
    virtual void OperationChangeState(Context*) = 0;
    virtual void OperationInterface(Context*) = 0;
    virtual ~State() { }
protected:
    bool ChangeState(Context* con, State *st);
};

class Context {
public:
    Context(State* st) {
        _st = st;
    }

    void OperationInterface() {
        _st->OperationInterface(this);
    }

    void OperationChangeState() {
        _st->OperationInterface(this);
    }
private:
    friend class State;
    bool ChangeState(State* st) {
        _st = st;
        return true;
    }

    State *_st;
};

bool State::ChangeState(Context* con, State *st) {
	return con->ChangeState(st);
}

class ConcreteStateA :public State {
public:
	ConcreteStateA() = default;
	void OperationChangeState(Context* con);
	void OperationInterface(Context* con);
};

class ConcreteStateB :public State {
public:
	ConcreteStateB() = default;
	void OperationChangeState(Context* con);
	void OperationInterface(Context* con);
};

void ConcreteStateA::OperationChangeState(Context* con) {
	OperationInterface(con);
	this->ChangeState(con, new ConcreteStateB());
}

void ConcreteStateA::OperationInterface(Context* con) {
	cout << "ConcreteStateA::OperationInterface..." << endl;
}

void ConcreteStateB::OperationChangeState(Context* con) {
	OperationInterface(con);
	this->ChangeState(con, new ConcreteStateB());
}

void ConcreteStateB::OperationInterface(Context* con) {
	cout << "ConcreteStateB::OperationInterface..." << endl;
}


int main() {
    State *st = new ConcreteStateA();
    Context *con = new Context(st);
    con->OperationInterface();
    con->OperationInterface();
    con->OperationInterface();

    delete con;
    delete st;

    return 0;
}
